package com.lanxin.bx.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.lanxin.bx.entity.BxInformal;
import com.lanxin.bx.entity.BxInformalaccessary;
import com.lanxin.bx.entity.BxInformaldetail;
import com.lanxin.bx.entity.BxInformaltype;
import com.lanxin.bx.service.IBxInformalService;
import com.lanxin.bx.service.IBxInformalaccessaryService;
import com.lanxin.bx.service.IBxInformaldetailService;
import com.lanxin.bx.service.IBxInformaltypeService;
import com.lanxin.bx.vo.AllinformalVo;
import com.lanxin.bx.vo.BxinformaldataVo;
import com.lanxin.bx.vo.jobvo;
import com.lanxin.hr.entity.ZzAccount;
import com.lanxin.hr.entity.ZzDepartment;
import com.lanxin.hr.entity.ZzEmployee;
import com.lanxin.hr.service.IZzDepartmentService;
import com.lanxin.hr.service.IZzEmployeeService;
import com.lanxin.judge.Vo.NodeVo;
import com.lanxin.judge.entity.LcApproval;
import com.lanxin.judge.entity.LcFlow;
import com.lanxin.judge.entity.LcNode;
import com.lanxin.judge.mapper.LcApprovalMapper;
import com.lanxin.judge.service.ILcApprovalService;
import com.lanxin.judge.service.ILcFlowService;
import com.lanxin.judge.service.ILcNodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Controller
@RequestMapping("/bx-informal")
public class BxInformalController {

    @Autowired
    private IBxInformalService bxInformalService;
    @Autowired
    private IBxInformaldetailService bxInformaldetailService;
    @Autowired
    private IBxInformaltypeService bxInformaltypeService;
    @Autowired
    private IZzDepartmentService departmentService;
    @Autowired
    private IZzEmployeeService employeeService;
    @Autowired
    private ILcFlowService lcFlowService;
    @Autowired
    private IBxInformalaccessaryService bxInformalaccessaryService;
    @Autowired
    private ILcApprovalService lcApprovalService;
    @Autowired
    private ILcNodeService lcNodeService;

    @RequestMapping("/toallinformallist")
    public ModelAndView toallinformallist(
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
            @RequestParam(value = "docNo", required = false) String docNo,
            @RequestParam(value = "empName", required = false) String empName,
            @RequestParam(value = "submitDate", required = false) String submitDate,
            @RequestParam(value = "status", required = false) String status) {

        // 调用服务层获取分页数据
        Page<AllinformalVo> bxInformalPage = bxInformalService.selectbxinformalList(
                page, pageSize, docNo, empName, submitDate, status);

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("bx/allinformal/allinformallist");

        // 添加分页数据到视图
        modelAndView.addObject("bxInformalPage", bxInformalPage);
        modelAndView.addObject("docNo", docNo);
        modelAndView.addObject("empName", empName);
        modelAndView.addObject("submitDate", submitDate);
        modelAndView.addObject("status", status);

        // 添加分页信息（可选）
        modelAndView.addObject("total", bxInformalPage.getTotal());
        modelAndView.addObject("pageNum", bxInformalPage.getPageNum());
        modelAndView.addObject("pageSize", bxInformalPage.getPageSize());
        modelAndView.addObject("pages", bxInformalPage.getPages()); // 总页数

        return modelAndView;
    }

    @RequestMapping("/tomyallinformallist")
    public ModelAndView tomyallinformallist(
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
            @RequestParam(value = "docNo", required = false) String docNo,
            @RequestParam(value = "submitDate", required = false) String submitDate,
            @RequestParam(value = "status", required = false) String status, HttpSession session) {


        // 调用服务层获取分页数据
        ZzAccount myaccount = (ZzAccount) session.getAttribute("myaccount");
        QueryWrapper<ZzEmployee> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("oid", myaccount.getAid());
        ZzEmployee employee= employeeService.getOne(queryWrapper);
        Page<AllinformalVo> bxInformalPage = bxInformalService.selectmybxinformalList(
                page, pageSize, docNo, submitDate, status,employee.getOid());

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("bx/allinformal/myallinformallist");

        // 添加分页数据到视图
        modelAndView.addObject("bxInformalPage", bxInformalPage);
        modelAndView.addObject("docNo", docNo);
        modelAndView.addObject("submitDate", submitDate);
        modelAndView.addObject("status", status);

        // 添加分页信息（可选）
        modelAndView.addObject("total", bxInformalPage.getTotal());
        modelAndView.addObject("pageNum", bxInformalPage.getPageNum());
        modelAndView.addObject("pageSize", bxInformalPage.getPageSize());
        modelAndView.addObject("pages", bxInformalPage.getPages()); // 总页数

        return modelAndView;
    }

    @GetMapping("/listDeptUseSelect")
    @ResponseBody // 重要：告诉Spring这是JSON响应
    public List<ZzDepartment> listDeptUseSelect() {
        return departmentService.list();
    }

    @GetMapping("/listDeptJobUseSelect")
    @ResponseBody
    public List<jobvo> listDeptJobUseSelect(@RequestParam("deptid") String deptid) {

        return bxInformalService.selectbxinformalJobList(deptid);
    }

    @GetMapping("/listEmpUseSelete")
    @ResponseBody
    public List<ZzEmployee> listEmpUseSelete(@RequestParam("deptid") String deptid) {
        QueryWrapper<ZzEmployee> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deptid", deptid);
        return employeeService.list(queryWrapper);
    }

    @GetMapping("/listEmpUseSelete2")
    @ResponseBody
    public List<ZzEmployee> listEmpUseSelete2(@RequestParam("deptid") String deptid,
                                              @RequestParam("jobid") String jobid) {
        QueryWrapper<ZzEmployee> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deptid", deptid);
        queryWrapper.eq("jobid", jobid);
        return employeeService.list(queryWrapper);
    }

    @RequestMapping("/reportBxInformal")
    public ModelAndView reportBxInformal(@RequestParam(value = "mode", defaultValue = "dept") String mode,
                                         @RequestParam(value = "type", defaultValue = "pie") String chartType,
                                         @RequestParam(value = "startDate", required = false) String startDate,
                                         @RequestParam(value = "endDate", required = false) String endDate) {

        ModelAndView modelAndView = new ModelAndView();
        List<BxinformaldataVo> statisticsList;
        if ("dept".equals(mode)) {
            statisticsList=bxInformalService.selectbxinformalDataListbydept(startDate, endDate);
        }else {
            statisticsList=bxInformalService.selectbxinformalDataListbytype(startDate, endDate);
        }

        modelAndView.setViewName("bx/reportInformal/reportInformallist");
        modelAndView.addObject("statisticsList", statisticsList);
        modelAndView.addObject("mode", mode);
        modelAndView.addObject("type", chartType);
        modelAndView.addObject("startDate", startDate);
        modelAndView.addObject("endDate", endDate);
        return modelAndView;
    }

    @GetMapping("/reportBxInformalPie")
    @ResponseBody
    public List<Map<String, Object>> getPieData(
            @RequestParam(value = "mode", defaultValue = "dept") String mode,
            @RequestParam(value = "startDate", required = false) String startDate,
            @RequestParam(value = "endDate", required = false) String endDate) {
        List<BxinformaldataVo> statisticsList;
        if ("dept".equals(mode)) {
            statisticsList = bxInformalService.selectbxinformalDataListbydept(startDate, endDate);
        } else {
            statisticsList = bxInformalService.selectbxinformalDataListbytype(startDate, endDate);
        }

        List<Map<String, Object>> pieData = new ArrayList<>();
        for (BxinformaldataVo item : statisticsList) {
            Map<String, Object> map = new HashMap<>();
            map.put("name", item.getName());
            map.put("value", item.getAmount());
            pieData.add(map);
        }

        return pieData;
    }


    @GetMapping("/reportBxInformalBar")
    @ResponseBody
    public Map<String, List<Object>> getBarData(
            @RequestParam(value = "mode", defaultValue = "dept") String mode,
            @RequestParam(value = "startDate", required = false) String startDate,
            @RequestParam(value = "endDate", required = false) String endDate) {
        List<BxinformaldataVo> statisticsList;
        if ("dept".equals(mode)) {
            statisticsList = bxInformalService.selectbxinformalDataListbydept(startDate, endDate);
        } else {
            statisticsList = bxInformalService.selectbxinformalDataListbytype(startDate, endDate);
        }

        Map<String, List<Object>> barData = new HashMap<>();
        List<Object> names = new ArrayList<>();
        List<Object> values = new ArrayList<>();

        for (BxinformaldataVo item : statisticsList) {
            names.add(item.getName());
            values.add(item.getAmount());
        }

        barData.put("name", names);
        barData.put("value", values);

        return barData;
    }


    @RequestMapping("/toallinformaledit")
    public ModelAndView toallinformaledit(@RequestParam(required = false) Integer oid) {
        ModelAndView modelAndView = new ModelAndView();
        QueryWrapper<LcFlow> LCqueryWrapper = new QueryWrapper<>();
        LCqueryWrapper.eq("state", "Y");
        LCqueryWrapper.eq("docType","BXD");
        List<LcFlow> lcFlow= lcFlowService.list(LCqueryWrapper);
        modelAndView.addObject("lcFlow", lcFlow);
        List<BxInformaltype> bxInformaltypes=bxInformaltypeService.list();
        modelAndView.addObject("bxInformaltypes", bxInformaltypes);
        BxInformal bxInformal;
        ZzEmployee employee = null;
        if (oid != null) {
            QueryWrapper<BxInformal> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("oid", oid);
            bxInformal=bxInformalService.getOne(queryWrapper);
            QueryWrapper<ZzEmployee> employeeQueryWrapper = new QueryWrapper<>();
            employeeQueryWrapper.eq("oid",bxInformal.getProposer());
             employee=employeeService.getOne(employeeQueryWrapper);
            List<BxInformaldetail> details = bxInformaldetailService.list(
                    new QueryWrapper<BxInformaldetail>()
                            .eq("parentid", oid)
            );
            modelAndView.addObject("details", details);
            //图片回显
            List<BxInformalaccessary> accessories = bxInformalaccessaryService.list(
                    new QueryWrapper<BxInformalaccessary>().eq("parentid", oid)
            );
            modelAndView.addObject("accessories", accessories);

        }else {
            bxInformal=new BxInformal();
        }
        modelAndView.addObject("bxInformal", bxInformal);
        modelAndView.addObject("employee", employee);
        modelAndView.setViewName("bx/allinformal/allinformallistedit");
        return modelAndView;
    }

    @RequestMapping("/toinformalcommit")
    @ResponseBody
    public boolean toinformalcommit(@RequestParam Integer oid){

        QueryWrapper<BxInformaldetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parentid",oid);
        long count = bxInformaldetailService.count(queryWrapper);
        if(count > 0){
            QueryWrapper< BxInformal> bxInformalQueryWrapper = new QueryWrapper<>();
            bxInformalQueryWrapper.eq("oid",oid);
            BxInformal bxInformal=bxInformalService.getOne(bxInformalQueryWrapper);
            String state="O";
            bxInformal.setStatus(state);
            bxInformal.setSubmitDate(LocalDateTime.now());
            bxInformalService.updateById(bxInformal);
            return true;
        }else {

        return false;

        }

    }

    @RequestMapping("/deleteinformal")
    @ResponseBody
    @Transactional
    public boolean deleteinformal(@RequestParam Integer oid) {
        // 1. 先删除所有附件（文件 + 数据库记录）
        List<BxInformalaccessary> accessories = bxInformalaccessaryService.list(
                new QueryWrapper<BxInformalaccessary>().eq("parentid", oid)
        );

        // 删除物理文件
        for (BxInformalaccessary accessory : accessories) {
            File file = new File(accessory.getContent());
            if (file.exists()) {
                file.delete();
            }
        }

        // 删除数据库记录
        bxInformalaccessaryService.remove(new QueryWrapper<BxInformalaccessary>().eq("parentid", oid));

        // 2. 删除明细表数据
        bxInformaldetailService.remove(new QueryWrapper<BxInformaldetail>().eq("parentid", oid));

        // 3. 最后删除主表数据
        return bxInformalService.removeById(oid);
    }

    @RequestMapping("/bxinformaledit")
    @Transactional
    public String bxinformaledit(BxInformal bxInformal,
                                 @RequestParam(value = "empName", required = false) String empName,
                                 @RequestParam(value = "typeid", required = false) Integer[] typeid,
                                 @RequestParam(value = "applyAmount", required = false) BigDecimal[] applyAmount,
                                 @RequestParam(value = "content", required = false) MultipartFile[] contentFiles,
                                 @RequestParam(value = "description", required = false) String[] descriptions,
                                 @RequestParam(value = "existingAccessoryOids", required = false) Integer[] existingAccessoryOids, // 用户保留的附件ID
                                 @RequestParam(value = "existingDescriptions", required = false) String[] existingDescriptions,  // 保留附件的新描述
                                 HttpSession session) {

        // ====== 基础状态设置 ======
        if (bxInformal.getStatus() == null || bxInformal.getStatus().trim().isEmpty()) {
            bxInformal.setStatus("W"); // 默认状态：待提交
        }

        // 获取当前登录用户信息
        ZzAccount myaccount = (ZzAccount) session.getAttribute("myaccount");
        if (myaccount == null) {
            throw new RuntimeException("用户未登录");
        }
        ZzEmployee employee = employeeService.getOne(new QueryWrapper<ZzEmployee>().eq("oid", myaccount.getAid()));
        if (employee == null) {
            throw new RuntimeException("用户信息不存在");
        }

        // 自动填充申请人姓名
        if (empName == null || empName.trim().isEmpty()) {
            empName = employee.getEmpName();
            bxInformal.setProposer(myaccount.getAid()); // 申请人
            bxInformal.setDeptid(employee.getDeptid()); // 部门ID
        }else {

            QueryWrapper<ZzEmployee> employeeQueryWrapper = new QueryWrapper<>();
            employeeQueryWrapper.eq("empName", empName);
            ZzEmployee employee1 = employeeService.getOne(employeeQueryWrapper);
            bxInformal.setProposer(employee1.getOid());
            bxInformal.setDeptid(employee1.getDeptid()); // 部门ID
        }

        // ====== 报销金额计算 ======
        BigDecimal totalAmount = BigDecimal.ZERO;
        if (applyAmount != null && applyAmount.length > 0) {
            for (BigDecimal amount : applyAmount) {
                if (amount != null) {
                    totalAmount = totalAmount.add(amount);
                }
            }
        }
        bxInformal.setApplyAmount(totalAmount);

        boolean isNew = bxInformal.getOid() == null;

        if (isNew) {

            LcFlow lcFlow = lcFlowService.getById(bxInformal.getFlowid());
            if (lcFlow == null) {
                throw new RuntimeException("审批流程不存在");
            }
            String docType = lcFlow.getDocType();
            String finalDocNo = docType + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));

            // 2. 设置主表基础信息（关键：先保存主表获取oid，再处理明细和附件）
            bxInformal.setDocNo(finalDocNo);
            bxInformal.setDoctype(docType);
            bxInformal.setFlowid(lcFlow.getOid()); // 确保流程ID正确
            bxInformal.setBooker(myaccount.getAid()); // 记账人
            bxInformal.setCreator(myaccount.getAid()); // 创建人
            bxInformal.setCreateDate(LocalDateTime.now()); // 创建时间
            bxInformal.setSubmitDate(null); // 未提交状态，提交时间为空
            bxInformalService.save(bxInformal); // 保存主表，获取自动生成的oid

            // 3. 保存报销明细（若有）
            if (typeid != null && typeid.length > 0 && applyAmount != null && applyAmount.length == typeid.length) {
                List<BxInformaldetail> details = new ArrayList<>();
                for (int i = 0; i < typeid.length; i++) {
                    BxInformaldetail detail = new BxInformaldetail();
                    detail.setParentid(bxInformal.getOid()); // 主表oid（已保存后获取）
                    detail.setTypeid(typeid[i]);
                    detail.setApplyAmount(applyAmount[i] != null ? applyAmount[i] : BigDecimal.ZERO);
                    details.add(detail);
                }
                bxInformaldetailService.saveBatch(details);
            } else if (typeid != null && typeid.length > 0) {
                throw new RuntimeException("报销类型与金额数量不匹配");
            }

            // 4. 新增模式：处理附件（核心修正：此处必须处理附件，原代码漏写！）
            saveAccessories(bxInformal.getOid(), contentFiles, descriptions, session);

            //5.添加审批单子
            LcApproval lcApproval = new LcApproval();
            lcApproval.setDoctype(bxInformal.getDoctype());
            lcApproval.setDocNo(bxInformal.getDocNo());
            lcApproval.setDocid(bxInformal.getOid());
            lcApproval.setProposer(myaccount.getAid());
            lcApproval.setDeptid(employee.getDeptid());
            lcApproval.setFlowid(bxInformal.getFlowid());
            List<NodeVo> lcNodes=lcNodeService.listNode(bxInformal.getFlowid());
            lcApproval.setNodeid(lcNodes.get(0).getOid());
            lcApproval.setStatus("O");
            lcApproval.setSubmitDate(LocalDateTime.now());
            lcApprovalService.save(lcApproval);

        } else {
            // ====== 编辑报销单 ======
            // 更新主表信息
            bxInformalService.updateById(bxInformal);

            // 处理报销明细（删除旧明细 + 保存新明细）
            bxInformaldetailService.remove(new QueryWrapper<BxInformaldetail>().eq("parentid", bxInformal.getOid()));
            if (typeid != null && typeid.length > 0 && applyAmount != null && applyAmount.length == typeid.length) {
                List<BxInformaldetail> details = new ArrayList<>();
                for (int i = 0; i < typeid.length; i++) {
                    BxInformaldetail detail = new BxInformaldetail();
                    detail.setParentid(bxInformal.getOid());
                    detail.setTypeid(typeid[i]);
                    detail.setApplyAmount(applyAmount[i] != null ? applyAmount[i] : BigDecimal.ZERO);
                    details.add(detail);
                }
                bxInformaldetailService.saveBatch(details);
            }

            // 处理附件（编辑模式：先删后加）
            Integer parentid = bxInformal.getOid();
            List<BxInformalaccessary> reservedAccessories = new ArrayList<>();

            // 1. 备份保留的旧附件
            if (existingAccessoryOids != null && existingAccessoryOids.length > 0) {
                reservedAccessories = bxInformalaccessaryService.list(
                        new QueryWrapper<BxInformalaccessary>()
                                .eq("parentid", parentid)
                                .in("oid", Arrays.asList(existingAccessoryOids))
                );
                // 更新保留附件描述
                for (int i = 0; i < reservedAccessories.size(); i++) {
                    BxInformalaccessary acc = reservedAccessories.get(i);
                    acc.setDescription((existingDescriptions != null && existingDescriptions.length > i) ? existingDescriptions[i] : "");
                }
            }

            // 2. 删除所有旧附件（文件 + 数据库）
            List<BxInformalaccessary> oldAccessories = bxInformalaccessaryService.list(new QueryWrapper<BxInformalaccessary>().eq("parentid", parentid));
            for (BxInformalaccessary acc : oldAccessories) {
                File file = new File(acc.getContent());
                if (file.exists()) {
                    file.delete(); // 删除文件
                }
            }
            bxInformalaccessaryService.remove(new QueryWrapper<BxInformalaccessary>().eq("parentid", parentid));

            // 3. 恢复保留的附件
            if (!reservedAccessories.isEmpty()) {
                bxInformalaccessaryService.saveBatch(reservedAccessories);
            }

            // 4. 保存新上传的附件
            saveAccessories(parentid, contentFiles, descriptions, session);
        }

        return "redirect:/bx-informal/tomyallinformallist";
    }

    // ====== 附件保存工具方法（抽取复用）======
    private void saveAccessories(Integer parentid, MultipartFile[] contentFiles, String[] descriptions, HttpSession session) {
        if (contentFiles == null || contentFiles.length == 0) {
            return; // 无附件，直接返回
        }

        List<BxInformalaccessary> accessories = new ArrayList<>();
        String savePath = session.getServletContext().getRealPath("/uploads/bx/accessory/");
        File dir = new File(savePath);
        if (!dir.exists()) {
            dir.mkdirs(); // 创建目录（确保目录存在，避免文件保存失败）
        }

        for (int i = 0; i < contentFiles.length; i++) {
            MultipartFile file = contentFiles[i];
            if (file.isEmpty()) {
                continue; // 跳过空文件
            }

            try {
                // 生成唯一文件名
                String originalFilename = file.getOriginalFilename();
                String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
                String fileName = UUID.randomUUID() + suffix;
                String filePath = savePath + fileName;

                // 保存文件到服务器
                file.transferTo(new File(filePath));

                // 添加到附件列表
                BxInformalaccessary accessory = new BxInformalaccessary();
                accessory.setParentid(parentid); // 主表oid（新增时已保存，非空）
                accessory.setContent(filePath);
                accessory.setDescription((descriptions != null && descriptions.length > i) ? descriptions[i] : "");
                accessories.add(accessory);

            } catch (Exception e) {
                throw new RuntimeException("附件上传失败：" + file.getOriginalFilename() + "，原因：" + e.getMessage());
            }
        }

        if (!accessories.isEmpty()) {
            bxInformalaccessaryService.saveBatch(accessories);
        }
    }

    //文件下载
    @RequestMapping("/downloadAccessory")
    public void downloadAccessory(@RequestParam Integer oid, HttpServletResponse response) {
        // 1. 查询附件信息
        BxInformalaccessary accessory = bxInformalaccessaryService.getById(oid);
        if (accessory == null) {
            response.setStatus(404);
            return;
        }

        // 2. 读取文件并返回给前端
        String filePath = accessory.getContent();
        File file = new File(filePath);
        if (!file.exists()) {
            response.setStatus(404); // 文件不存在
            return;
        }

        try (InputStream in = new FileInputStream(file);
             OutputStream out = response.getOutputStream()) {
            // 设置响应头（文件名使用原始名，这里简化为UUID，实际可从附件表存储原始名）
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + UUID.randomUUID() + ".jpg");
            // 写入文件流
            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            response.setStatus(500);
        }
    }

    @RequestMapping("/payeeInformal")
    public String payeeInformal(
            @RequestParam Integer oid,
            @RequestParam Integer payee,
            @RequestParam(required = false) Integer[] doid,
            @RequestParam(required = false) BigDecimal[] amount
    ) {
        if (oid == null || payee == null) {
            throw new RuntimeException("报销单ID和领款人ID不能为空");
        }
        if (doid == null || amount == null || doid.length != amount.length) {
            throw new RuntimeException("明细ID与金额数量不匹配");
        }

        BxInformal bxInformal = bxInformalService.getById(oid);
        if (bxInformal == null) {
            throw new RuntimeException("报销单不存在");
        }

        List<BxInformaldetail> detailsToUpdate = new ArrayList<>();
        BigDecimal totalAmount = BigDecimal.ZERO;

        for (int i = 0; i < doid.length; i++) {
            Integer detailId = doid[i];
            BigDecimal amount1 = amount[i] != null ? amount[i] : BigDecimal.ZERO;

            BxInformaldetail detail = bxInformaldetailService.getById(detailId);
            if (detail == null || !detail.getParentid().equals(oid)) {
                throw new RuntimeException("明细记录不存在或不属于当前报销单");
            }

            detail.setAmount(amount1);
            detailsToUpdate.add(detail);
            totalAmount = totalAmount.add(amount1);
        }

        if (!detailsToUpdate.isEmpty()) {
            bxInformaldetailService.updateBatchById(detailsToUpdate);
        }

        bxInformal.setPayee(payee);
        bxInformal.setBookDate(LocalDateTime.now());
        bxInformal.setBookAmount(totalAmount);
        bxInformal.setStatus("S");
        bxInformalService.updateById(bxInformal);

        return "redirect:/bx-informal/toallinformallist";
    }


}
